#ifndef __IM_ATTRIBUTES_H__
#define __IM_ATTRIBUTES_H__

#include <im_base_types.h>
#include <im_object.h>

/**
 * @defgroup IMAttribute
 * @ingroup PublicIME
 * @{
 */

/** @struct IMAttribute
 *  @brief It's the common base class of all text attribute types.
 *
 * It hold the range to which the real text attribute applied.
 * - IMUInt start   the start position of the range (in unicode characters).
 * - IMUInt end     the end position of the range, the character at this
 *                  position is not included in the range.
 *
 * So that the range covers unicode characters in [start,end).
 *
 * the following text attribute types can be supported:
 * - IM_TYPE_ATTR_FOREGROUND            text foreground color
 * - IM_TYPE_ATTR_BACKGROUND            text background color
 * - IM_TYPE_ATTR_UNDERLINE             underline
 * - IM_TYPE_ATTR_UNDERLINE_COLOR       underline color
 * - IM_TYPE_ATTR_STRIKETHROUGH         strikethrough
 * - IM_TYPE_ATTR_STRIKETHROUGH_COLOR   strikethrough color
 * - IM_TYPE_ATTR_HIGHLIGHT             highlight
 * - IM_TYPE_ATTR_REVERSE               reverse
 * - IM_TYPE_ATTR_LANGUAGE              text language
 *   an iso639-1 language code with optional iso3166 region code.
 *   such as "zh-cn", "ja", etc.
 * - IM_TYPE_ATTR_FONT_FAMILY           font family, such as "Sans"
 * - IM_TYPE_ATTR_FONT_STYLE            font style, such as italic.
 * - IM_TYPE_ATTR_FONT_WEIGHT           font weight, such as bold.
 * - IM_TYPE_ATTR_FONT_SIZE             font size in 1/1000 point. Such as 10000 means 10 points.
 *   Normally 1 point = 1/72 inch = 0.35278 mm.
 * - IM_TYPE_ATTR_FONT_SCALE            scale factor of font size. in percent, 100 means no scale.
 *   The base font for the affected text will have its size multiplied by scale_factor/1000.
 *   If font size of the text is not specified, client or GUI component will use its default font
 *   size to calculate the scaled font size.
 * - IM_TEXT_ATTR_STRING                an arbitrary string.
 * - IM_TEXT_ATTR_OBJECT                an arbitrary object.
 */
/** @struct IMAttrColor
 * @brief It is used to represent attributes that are colors.
 *
 * An IMAttrColor attribute has three data member: red, green and blue, they
 * shall be in the range between 0-65535.
 * (red, green, blue) = (0, 0, 0) indicates black color.
 * (red, green, blue) = (65535, 65535, 65535) indicates white color.
 *
 * color attributes include:
 * - foreground color
 * - background color
 * - underline color
 * - strikethrough color
 *
 * All of these attributes use this same object structure.
 */
/** @struct IMAttrInt
 * @brief It is used to represent attributes with an integer or enumeration value.
 *
 * - underline
 * - font style
 * - font weight
 * - font size
 * - font scale
 */
/** @struct IMAttrString
 * @brief It is used to represent attributes with a string value.
 *
 * - language
 * - font family
 * - string
 */
/** @struct IMAttrObject
 * @brief It is used to represent attributes with an object.
 */
/** @enum IMAttrUnderline
 * @brief Types of underline.
 *
 * - IM_ATTR_UNDERLINE_SINGLE   single underline
 * - IM_ATTR_UNDERLINE_DOUBLE   double underline
 * - IM_ATTR_UNDERLINE_WAVE     wavy underline
 */
/** @enum IMAttrFontStyle
 * @brief Possible font styles.
 *
 * - IM_ATTR_FONT_STYLE_NORMAL  normal font style
 * - IM_ATTR_FONT_STYLE_OBLIQUE slanted with roman style
 * - IM_ATTR_FONT_STYLE_ITALIC  slanted with italic style
 */
/** @enum IMAttrFontWeight
 * @brief Possible font weights.
 *
 * - IM_ATTR_FONT_WEIGHT_NORMAL normal weight
 * - IM_ATTR_FONT_WEIGHT_BOLD   bold weight
 */

/** @struct IMAttrList
 * @brief A structure to hold a list of attributes that apply to a section of text.
 *
 * The attributes are, in general, allowed to overlap in an arbitrary fashion,
 * however, if the attributes are manipulated only through im_attr_list_change(),
 * the overlap between attributes will meet stricter criteria.
 */
/** @struct IMAttrIterator
 * @brief A structure to represent an Iterator through a IMAttrList.
 *
 * A new iterator is created with im_attr_list_get_iterator().
 * Once the iterator is created, it can be advanced through each
 * attributes in the list using im_attr_iterator_next().
 * The iterator will be invalidated if the the list is changed.
 */


IM_BEGIN_DECLS

/** @brief cast the pointer to IMAttribute*, return NULL if failed. */
#define IM_ATTRIBUTE(p)                 (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTRIBUTE,IMAttribute))
/** @brief cast the pointer to const IMAttribute*, return NULL if failed. */
#define IM_CONST_ATTRIBUTE(p)           (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTRIBUTE,IMAttribute))
/** @brief cast the pointer to IMAttributeClass*, return NULL if failed. */
#define IM_ATTRIBUTE_CLASS(c)           (IM_TYPE_CLASS_CHECK_CAST((c),IM_TYPE_ATTRIBUTE,IMAttributeClass))
/** @brief tell if the pointer is an instance of IMAttribute */
#define IM_IS_ATTRIBUTE(p)              (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTRIBUTE))
/** @brief tell if the pointer is an IMAttributeClass */
#define IM_IS_ATTRIBUTE_CLASS(c)        (IM_TYPE_CLASS_CHECK_TYPE((c),IM_TYPE_ATTRIBUTE))
/** @brief get the IMAttributeClass from an instance of IMAttribute */
#define IM_ATTRIBUTE_GET_CLASS(p)       (IM_TYPE_INSTANCE_GET_CLASS_CAST((p),IM_TYPE_ATTRIBUTE,IMAttributeClass))
/** @brief get the type id from an instance of IMAttribute */
#define IM_ATTRIBUTE_TYPE(p)            (im_object_get_type (p))

/** @brief cast the pointer to IMAttrList*, return NULL if failed. */
#define IM_ATTR_LIST(p)                 (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_LIST,IMAttrList))
/** @brief cast the pointer to const IMAttrList*, return NULL if failed. */
#define IM_CONST_ATTR_LIST(p)           (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_LIST,IMAttrList))
/** @brief cast the pointer to IMAttrListClass*, return NULL if failed. */
#define IM_ATTR_LIST_CLASS(c)           (IM_TYPE_CLASS_CHECK_CAST((c),IM_TYPE_ATTR_LIST,IMAttrListClass))
/** @brief tell if the pointer is an instance of IMAttrList */
#define IM_IS_ATTR_LIST(p)              (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_LIST))
/** @brief tell if the pointer is an IMAttrListClass */
#define IM_IS_ATTR_LIST_CLASS(c)        (IM_TYPE_CLASS_CHECK_TYPE((c),IM_TYPE_ATTR_LIST))
/** @brief get the type id from an instance of IMAttrList */
#define IM_ATTR_LIST_GET_CLASS(p)       (IM_TYPE_INSTANCE_GET_CLASS_CAST((p),IM_TYPE_ATTR_LIST,IMAttrListClass))

/** @brief cast the pointer to a language attribute object, return NULL if failed. */
#define IM_ATTR_LANGUAGE(p)             (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_LANGUAGE,IMAttrString))
/** @brief cast the pointer to a font family attribute object, return NULL if failed. */
#define IM_ATTR_FONT_FAMILY(p)          (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_FONT_FAMILY,IMAttrString))
/** @brief cast the pointer to a font style attribute object, return NULL if failed. */
#define IM_ATTR_FONT_STYLE(p)           (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_FONT_STYLE,IMAttrInt))
/** @brief cast the pointer to a font weight attribute object, return NULL if failed. */
#define IM_ATTR_FONT_WEIGHT(p)          (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_FONT_WEIGHT,IMAttrInt))
/** @brief cast the pointer to a font size attribute object, return NULL if failed. */
#define IM_ATTR_FONT_SIZE(p)            (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_FONT_SIZE,IMAttrInt))
/** @brief cast the pointer to a font scale attribute object, return NULL if failed. */
#define IM_ATTR_FONT_SCALE(p)           (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_FONT_SCALE,IMAttrInt))
/** @brief cast the pointer to a foreground attribute object, return NULL if failed. */
#define IM_ATTR_FOREGROUND(p)           (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_FOREGROUND,IMAttrColor))
/** @brief cast the pointer to a background attribute object, return NULL if failed. */
#define IM_ATTR_BACKGROUND(p)           (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_BACKGROUND,IMAttrColor))
/** @brief cast the pointer to a underline attribute object, return NULL if failed. */
#define IM_ATTR_UNDERLINE(p)            (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_UNDERLINE,IMAttrInt))
/** @brief cast the pointer to a underline color attribute object, return NULL if failed. */
#define IM_ATTR_UNDERLINE_COLOR(p)      (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_UNDERLINE_COLOR,IMAttrColor))
/** @brief cast the pointer to a strikethrough attribute object, return NULL if failed. */
#define IM_ATTR_STRIKETHROUGH(p)        (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_STRIKETHROUGH,IMAttribute))
/** @brief cast the pointer to a strikethrough color attribute object, return NULL if failed. */
#define IM_ATTR_STRIKETHROUGH_COLOR(p)  (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_STRIKETHROUGH_COLOR,IMAttrColor))
/** @brief cast the pointer to a highlight attribute object, return NULL if failed. */
#define IM_ATTR_HIGHLIGHT(p)            (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_HIGHLIGHT,IMAttribute))
/** @brief cast the pointer to a reverse attribute object, return NULL if failed. */
#define IM_ATTR_REVERSE(p)              (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_REVERSE,IMAttribute))
/** @brief cast the pointer to a string attribute object, return NULL if failed. */
#define IM_ATTR_STRING(p)               (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_STRING,IMAttrString))
/** @brief cast the pointer to an attribute object holds another object, return NULL if failed. */
#define IM_ATTR_OBJECT(p)               (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_ATTR_OBJECT,IMAttrObject))

/** @brief cast the pointer to a const reference of language attribute object, return NULL if failed. */
#define IM_CONST_ATTR_LANGUAGE(p)             (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_LANGUAGE,IMAttrString))
/** @brief cast the pointer to a const reference of font family attribute object, return NULL if failed. */
#define IM_CONST_ATTR_FONT_FAMILY(p)          (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_FONT_FAMILY,IMAttrString))
/** @brief cast the pointer to a const reference of font style attribute object, return NULL if failed. */
#define IM_CONST_ATTR_FONT_STYLE(p)           (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_FONT_STYLE,IMAttrInt))
/** @brief cast the pointer to a const reference of font weight attribute object, return NULL if failed. */
#define IM_CONST_ATTR_FONT_WEIGHT(p)          (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_FONT_WEIGHT,IMAttrInt))
/** @brief cast the pointer to a const reference of font size attribute object, return NULL if failed. */
#define IM_CONST_ATTR_FONT_SIZE(p)            (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_FONT_SIZE,IMAttrInt))
/** @brief cast the pointer to a const reference of font scale attribute object, return NULL if failed. */
#define IM_CONST_ATTR_FONT_SCALE(p)           (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_FONT_SCALE,IMAttrInt))
/** @brief cast the pointer to a const reference of foreground attribute object, return NULL if failed. */
#define IM_CONST_ATTR_FOREGROUND(p)           (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_FOREGROUND,IMAttrColor))
/** @brief cast the pointer to a const reference of background attribute object, return NULL if failed. */
#define IM_CONST_ATTR_BACKGROUND(p)           (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_BACKGROUND,IMAttrColor))
/** @brief cast the pointer to a const reference of underline attribute object, return NULL if failed. */
#define IM_CONST_ATTR_UNDERLINE(p)            (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_UNDERLINE,IMAttrInt))
/** @brief cast the pointer to a const reference of underline color attribute object, return NULL if failed. */
#define IM_CONST_ATTR_UNDERLINE_COLOR(p)      (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_UNDERLINE_COLOR,IMAttrColor))
/** @brief cast the pointer to a const reference of strikethrough attribute object, return NULL if failed. */
#define IM_CONST_ATTR_STRIKETHROUGH(p)        (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_STRIKETHROUGH,IMAttribute))
/** @brief cast the pointer to a const reference of strikethrough color attribute object, return NULL if failed. */
#define IM_CONST_ATTR_STRIKETHROUGH_COLOR(p)  (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_STRIKETHROUGH_COLOR,IMAttrColor))
/** @brief cast the pointer to a const reference of highlight attribute object, return NULL if failed. */
#define IM_CONST_ATTR_HIGHLIGHT(p)            (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_HIGHLIGHT,IMAttribute))
/** @brief cast the pointer to a const reference of reverse attribute object, return NULL if failed. */
#define IM_CONST_ATTR_REVERSE(p)              (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_REVERSE,IMAttribute))
/** @brief cast the pointer to a const reference of string attribute object, return NULL if failed. */
#define IM_CONST_ATTR_STRING(p)               (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_STRING,IMAttrString))
/** @brief cast the pointer to a const reference of an attribute object holds another object, return NULL if failed. */
#define IM_CONST_ATTR_OBJECT(p)               (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_ATTR_OBJECT,IMAttrObject))

/** @brief tell if the pointer is an instance of language attribute */
#define IM_IS_ATTR_LANGUAGE(p)             (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_LANGUAGE))
/** @brief tell if the pointer is an instance of font family attribute */
#define IM_IS_ATTR_FONT_FAMILY(p)          (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_FONT_FAMILY))
/** @brief tell if the pointer is an instance of font size attribute */
#define IM_IS_ATTR_FONT_STYLE(p)           (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_FONT_STYLE))
/** @brief tell if the pointer is an instance of font weight attribute */
#define IM_IS_ATTR_FONT_WEIGHT(p)          (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_FONT_WEIGHT))
/** @brief tell if the pointer is an instance of font size attribute */
#define IM_IS_ATTR_FONT_SIZE(p)            (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_FONT_SIZE))
/** @brief tell if the pointer is an instance of font scale attribute */
#define IM_IS_ATTR_FONT_SCALE(p)           (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_FONT_SCALE))
/** @brief tell if the pointer is an instance of foreground attribute */
#define IM_IS_ATTR_FOREGROUND(p)           (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_FOREGROUND))
/** @brief tell if the pointer is an instance of background attribute */
#define IM_IS_ATTR_BACKGROUND(p)           (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_BACKGROUND))
/** @brief tell if the pointer is an instance of underline attribute */
#define IM_IS_ATTR_UNDERLINE(p)            (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_UNDERLINE))
/** @brief tell if the pointer is an instance of underline color attribute */
#define IM_IS_ATTR_UNDERLINE_COLOR(p)      (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_UNDERLINE_COLOR))
/** @brief tell if the pointer is an instance of strikethrough attribute */
#define IM_IS_ATTR_STRIKETHROUGH(p)        (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_STRIKETHROUGH))
/** @brief tell if the pointer is an instance of strikethrough color attribute */
#define IM_IS_ATTR_STRIKETHROUGH_COLOR(p)  (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_STRIKETHROUGH_COLOR))
/** @brief tell if the pointer is an instance of highlight attribute */
#define IM_IS_ATTR_HIGHLIGHT(p)            (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_HIGHLIGHT))
/** @brief tell if the pointer is an instance of reverse attribute */
#define IM_IS_ATTR_REVERSE(p)              (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_REVERSE))
/** @brief tell if the pointer is an instance of string attribute */
#define IM_IS_ATTR_STRING(p)               (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_STRING))
/** @brief tell if the pointer is an instance of attribute object holds another object */
#define IM_IS_ATTR_OBJECT(p)               (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_ATTR_OBJECT))

typedef struct _IMAttribute             IMAttribute;
typedef struct _IMAttributeClass        IMAttributeClass;

typedef struct _IMAttrColor             IMAttrColor;
typedef struct _IMAttrInt               IMAttrInt;
typedef struct _IMAttrString            IMAttrString;
typedef struct _IMAttrObject            IMAttrObject;

typedef struct _IMAttrList              IMAttrList;
typedef struct _IMAttrListClass         IMAttrListClass;
typedef struct _IMAttrIterator          IMAttrIterator;

typedef enum {
    IM_ATTR_UNDERLINE_NONE,
    IM_ATTR_UNDERLINE_SINGLE,
    IM_ATTR_UNDERLINE_DOUBLE,
    IM_ATTR_UNDERLINE_WAVE
} IMAttrUnderline;

typedef enum {
    IM_ATTR_FONT_STYLE_NORMAL,
    IM_ATTR_FONT_STYLE_OBLIQUE,
    IM_ATTR_FONT_STYLE_ITALIC
} IMAttrFontStyle;

typedef enum {
    IM_ATTR_FONT_WEIGHT_NORMAL,
    IM_ATTR_FONT_WEIGHT_BOLD
} IMAttrFontWeight;

struct _IMAttribute
{
    IMObject object;

    IMUInt   start;
    IMUInt   end;
};

struct _IMAttributeClass
{
    IMObjectClass parent_class;

    void    (*clear)    (IMAttribute            *attr);
    IMBool  (*equal)    (const IMAttribute      *attr1,
                         const IMAttribute      *attr2);
};

struct _IMAttrColor
{
    IMAttribute attr;

    IMUInt16    red;
    IMUInt16    green;
    IMUInt16    blue;
};

struct _IMAttrInt
{
    IMAttribute attr;

    IMInt       value;
};

struct _IMAttrString
{
    IMAttribute attr;

    IMChar      *str;
    IMBool      nocopy;
};

struct _IMAttrObject
{
    IMAttribute attr;

    IMPointer   object;
};

/**
 * @brief helper macro to get start position of an attribute.
 */
#define                 im_attribute_get_start(attr)    (((IMAttribute*)(attr))->start)
/**
 * @brief helper macro to get end position of an attribute.
 */
#define                 im_attribute_get_end(attr)      (((IMAttribute*)(attr))->end)
/**
 * @brief helper macro to get length of an attribute.
 */
#define                 im_attribute_get_length(attr)   (im_attribute_end(attr) - im_attribute_start(attr))

/**
 * @brief Create an empty IMAttribute object with a specific attribute type.
 *
 * This function creates an empty instance of IMAttribute with IMType which is 
 * specified by parameter type.
 *
 * @param type The type of newly created attribute object,
 *             it shall be derived from IM_TYPE_ATTRIBUTE.
 * @return newly created instance of IMAttribute which shall be unreferenced by
 *         im_object_unref when no longer needed or NULL if type is not an 
 *         IM_TYPE_ATTRIBUTE type.
 */
IMAttribute*            im_attribute_new                (IMType                  type);
/**
 * @brief Clear the content of an attribute.
 *
 * This function clears the content of the argument attr, or do nothing if the
 * pointer specified by the argument attr is not IMAttribute type.
 *
 * @param attr a pointer to an instance of IMAttribute
 *
 * @return This function returns no value.
 */
void                    im_attribute_clear              (IMAttribute            *attr);
/**
 * @brief Set the start position of an attribute.
 *
 * This function sets the start position of the range where the argument attr
 * is applied as the argument start. If the argument start is greater than the
 * end, the end position shall be changed to same position as the argument
 * start. If the argument attr is not a pointer to an instance of IMAttribute
 * type, this function shall do nothing.
 *
 * @param attr a pointer to an instance of IMAttribute
 * @param start new start position
 *
 * @return This function returns no value.
 */
void                    im_attribute_set_start          (IMAttribute            *attr,
                                                         IMUInt                  start);
/**
 * @brief Set the end position of an attribute.
 *
 * This function sets the end position of the range where the argument attr is
 * applied as the argument end. If the argument end is less than the start
 * position, the start position shall be changed to same position as the
 * argument end. The end poisition itself shall not be included in the range of
 * the argument attr. If the argument attr is not a pointer to an instance of
 * IMAttribute type, this function shall do nothing.
 *
 * @param attr a pointer to an instance of IMAttribute
 * @param end new end value.
 *
 * @return This function returns no value.
 */
void                    im_attribute_set_end            (IMAttribute            *attr,
                                                         IMUInt                  end);
/**
 * @brief Set the length of an attribute.
 *
 * This function shall adjust the end position of the argument attr according
 * to the argument length. The length is defined as the difference between the
 * start and the end. If the argument attr is not a pointer to an instance of
 * IMAttribute type, this function shall do nothing.
 *
 * @param attr a pointer to an instance of IMAttribute
 * @param length the new length for the arugment attr
 *
 * @return This function returns no value.
 */
void                    im_attribute_set_length         (IMAttribute            *attr,
                                                         IMUInt                  length);
/**
 * @brief Get the range of an attribute.
 *
 * This function shall copy the start and end of the range of the argument
 * attr. If the argument start or end is NULL, this function shall not copy
 * the values. If the argument attr is not a pointer to an instance of
 * IMAttribute type, this function shall do nothing and the value of the
 * argument start and end are not defined.
 *
 * @param attr  a pointer to an instance of IMAttribute
 * @param start a pointer to IMUInt where the start value shall be copied
 * @param end   a pointer to IMUInt where the end value shall be copied
 *
 * @return This function returns no value.
 */
void                    im_attribute_get_range          (const IMAttribute      *attr,
                                                         IMUInt                 *start,
                                                         IMUInt                 *end);
/**
 * @brief Set the range of an attribute.
 *
 * This function sets the range where the argument attr is applied according to
 * the argument start and the arugment end. If the arugment start is greater
 * than the argument end, the argument end shall be the start position and the
 * argument start shall be the end position. If the argument attr is not a
 * pointer to an instance of IMAttribute type, this function shall do nothing.
 *
 * @param attr  a pointer to an instance of IMAttribute
 * @param start new start position
 * @param end   new end position
 *
 * @return This function returns no value.
 */
void                    im_attribute_set_range          (IMAttribute            *attr,
                                                         IMUInt                  start,
                                                         IMUInt                  end);
/**
 * @brief Check whether two attributes are equal.
 *
 * This function compares the argument attr1 and the argument attr2.  Only
 * content of the attributes shall be compared.  Their range will not be taken
 * into account. If the arguments attr1 or attr2 is NULL or not a type of
 * IMAttribute, this function shall return FALSE. If the arguments are not the
 * same type, this function also return FALSE.
 *
 * @param attr1 a pointer to an instance of IMAttribute.
 * @param attr2 a pointer to an instance of IMAttribute.
 *
 * @return TRUE if the two argument are the same type and have the same value,
 *         or FALSE.
 */
IMBool                  im_attribute_equal              (const IMAttribute      *attr1,
                                                         const IMAttribute      *attr2);

/**
 * @brief Create a new language attribute object.
 *
 * This function create a new instance of IM_TYPE_ATTR_LANGUAGE IMAttribute.
 *
 * @param lang a pointer to a language code string, which is specified by ISO639-1.
 * @return newly created IMAttribute instance pointer. This pointer shall be
 *         unrefenced by im_object_unref when no longer needed.
 */
IMAttribute*            im_attr_language_new            (const IMChar           *lang);
/**
 * @brief Get the language string from the given attribute object.
 *
 * This function returns the language code string the the argument attr. If the
 * argument attr is not a IM_TYPE_LANGUAGE type, this function shall return
 * NULL.
 *
 * @param a pointer to an instance of IMAttribute.
 *
 * @return a pointer to the language code, which shall not be changed by user
 *         or freed.
 */
const IMChar*           im_attr_language_get            (const IMAttribute      *attr);
/**
 * @brief Set the language in the given attribute object.
 *
 * This function shall change the language code string which the argument attr
 * represents with the argument lang.
 *
 * @param attr a pointer to an instance of IMAttribute.
 * @param lang a pointer to the language code string.
 *
 * @return This function returns no value.
 */
void                    im_attr_language_set            (IMAttribute            *attr,
                                                         const IMChar           *lang);
/**
 * @brief  Set the language in the given attribute object with a static string.
 *
 * This function shall set the language code string as the argument lang, so
 * the argument lang shall be available through the life time of the argument
 * attr.
 *
 * @param attr a pointer to an instance of IMAttribute.
 * @param lang a pointer to the language code string.
 *
 * @return This function returns no value.
 */
void                    im_attr_language_set_static     (IMAttribute            *attr,
                                                         const IMChar           *lang);

/**
 * @brief Create a new font family attribute object.
 *
 * This function creates a new instance of IMAttribute of IM_TYPE_ATTR_FONT_FAMILY.
 *
 * @param family string to the font family name.
 *
 * @return This function returns a newly created instance of IM_TYPE_FONTFAMILY
 *         type IMAttribute.
 */
IMAttribute*            im_attr_font_family_new         (const IMChar           *family);
/**
 * @brief Get the font family string from the given attribute object.
 *
 * This function returns the font family name string, which the argument attr
 * represents.
 *
 * @param attr a pointer to an instance of IMAttribute.
 *
 * @return This function returns the font family string, which shall not be
 *         modified or freed by user.
 */
const IMChar*           im_attr_font_family_get         (const IMAttribute      *attr);
/**
 * @brief Set the font family in the given attribute object.
 *
 * This function changes the font family name of the argument attr with the
 * argument family.
 *
 * @param attr   a pointer to an instance of IMAttribute.
 * @param family a pointer to the font family name string.
 *
 * @return This function returns no value.
 */
void                    im_attr_font_family_set         (IMAttribute            *attr,
                                                         const IMChar           *family);
/**
 * @brief Set the font family in the given attribute object with a static string.
 *
 * This function shall set the font family name string as the argument family,
 * so the argument family shall be available through the life time of the
 * argument attr.
 *
 * @param attr   a pointer to an instance of IMAttribute.
 * @param family a pointer to the font family name string.
 *
 * @return This function returns no value.
 */
void                    im_attr_font_family_set_static  (IMAttribute            *attr,
                                                         const IMChar           *family);

/**
 * @brief Create a new font style attribute object.
 *
 * This function returns a newly created IM_TYPE_ATTR_FONT_STYLE type IMAttribute.
 *
 * @param style  an IMAttrFontStyle value to specify font style.
 *
 * @return This function returns a pointer to an instance of IMAttribute, which
 *         shall be unreferenced when no longer needed.
 */
IMAttribute*            im_attr_font_style_new          (IMAttrFontStyle         style);
/**
 * @brief Get the font style from the given attribute object.
 *
 * This function returns font style value which the argument attr represents.
 *
 * @param attr a pointer to an instance of IMAttribute.
 *
 * @return This function returns IMAttrFontStyle value which the argument attr
 *         represents. If the argument attr is not an IM_TYPE_ATTR_FONT_STYLE,
 *         this function returns IM_ATTR_FONT_STYLE_NORMAL.
 */
IMAttrFontStyle         im_attr_font_style_get          (const IMAttribute      *attr);
/**
 * @brief Set the font style in the given attribute object.
 *
 * This function changes the font style value of the argument attr with the
 * argument style. If the argument attr is not a type of
 * IM_TYPE_ATTR_FONT_STYLE, this function shall do nothing.
 *
 * @param attr a pointer to an instance of IMAttribute.
 * @param style  an IMAttrFontStyle value to specify font style.
 *
 * @return This function returns no value.
 */
void                    im_attr_font_style_set          (IMAttribute            *attr,
                                                         IMAttrFontStyle         style);

/**
 * @brief Create a new font weight attribute object.
 *
 * This function returns a newly created IMAttribute which represents font
 * weight.
 *
 * @param weight IMAttrFontWeight value to specify font weight.
 *
 * @return This function returns a newly created IM_TYPE_ATTR_FONT_WEIGHT type
 *         IMAttribute pointer, which shall be unreferenced when no longer
 *         needed.
 */
IMAttribute*            im_attr_font_weight_new         (IMAttrFontWeight        weight);
/**
 * @brief Get the font weight from the given attribute object.
 *
 * This function returns the font weight value which the argument attr
 * represents.
 *
 * @param attr a pointer to an instance of IMAttribute.
 *
 * @return This function returns IMAttrFontWeight value which the argument
 *         attr represents, or IM_ATTR_FONT_WEIGHT_NORMAL if the argument attr
 *         is not an IM_TYPE_ATTR_FONT_WEIGHT type.
 */
IMAttrFontWeight        im_attr_font_weight_get         (const IMAttribute      *attr);
/**
 * @brief Set the font weight in the given attribute object.
 *
 * This function set the font weight value of the argument attr. If the
 * argument attr is not a pointer to a IM_TYPE_ATTR_FONT_WEIGHT, this function
 * shall do nothing.
 *
 * @param attr a pointer to an instance of IMAttribute.
 * @param weight new value font weight value for attr.
 *
 * @return This function returns no value.
 */
void                    im_attr_font_weight_set         (IMAttribute            *attr,
                                                         IMAttrFontWeight        weight);

/**
 * @brief Create a new font size attribute object.
 *
 * This function returns a newly created an instance of IMAttribute which
 * represents font size.
 *
 * @param size font size
 *
 * @return This function returns an instance of IM_TYPE_ATTR_FONT_SIZE
 *         IMAttribute, which shall be unreferenced when no longer needed.
 */
IMAttribute*            im_attr_font_size_new           (IMInt                   size);
/**
 * @brief Get the font size from the given attribute object.
 *
 * This function returns the font weight value which the argument attr
 * represents.
 *
 * @param attr a pointer to an instance of IMAttribute.
 *
 * @return This function returns IMAttrFontSize value which the argument
 *         attr represents, or 0 if the argument attr is not an
 *         IM_TYPE_ATTR_FONT_SIZE type. This value is in 1/1000 point.
 */
IMInt                   im_attr_font_size_get           (const IMAttribute      *attr);
/**
 * @brief Set the font size in the given attribute object.
 *
 * This function change the font size value which the argument attr represents
 * with the argument size. If the argument attr is not an
 * IM_TYPE_ATTR_FONT_WEIGHT type, this function shall do nothing.
 *
 * @param attr a pointer to an instance of IMAttribute.
 * @param size font size for the argument attr in 1/1000 point.
 *
 * @return This function set font size value which the argument attr
 *         represents. If the argument attr is not an IM_TYPE_ATTR_FONT_SIZE
 *         type, this function shall do nothing.
 */
void                    im_attr_font_size_set           (IMAttribute            *attr,
                                                         IMInt                   size);

/**
 * @brief Create a new font scale attribute object.
 *
 * This function returns a newly created instance of IM_TYPE_ATTR_FONT_SCALE
 * type which represents the font scale with the argument scale_factor. If the
 * font size attribute is already specified in IMText, the font size shall be
 * scaled by this factor.
 *
 * @param scale_factor value for font scale in percent.
 *
 * @return This function returns a newly created instance of
 *         IM_TYPE_ATTR_FONT_SCALE.
 */
IMAttribute*            im_attr_font_scale_new          (IMInt                   scale_factor);
/**
 * @brief Get the font scale factor from the given attribute object.
 *
 * This function returns the scale factor of the argument attr.
 *
 * @param attr a pointer to an instance of IMAttribute.
 *
 * @return This function returns a font scale factor value, or 0 if the
 *         argument attr is not a type of IM_TYPE_ATTR_FONT_SCALE.
 */ 
IMInt                   im_attr_font_scale_get          (const IMAttribute      *attr);
/**
 * @brief Set the font scale factor in the given attribute object.
 *
 * This function change the font scale factor value of the argument attr with
 * the argument scale_factor. If the argument attr is not a type of
 * IM_TYPE_ATTR_FONT_SCALE, this function shall do nothing.
 *
 * @param attr a pointer to an instance of IMAttribute.
 * @param scale_factor font scale factor for the argument attr.
 *
 * @return This function returns no value.
 */ 
void                    im_attr_font_scale_set          (IMAttribute            *attr,
                                                         IMInt                   scale_factor);

/**
 * @brief Create a new foreground attribute object with RGB color.
 *
 * This function creates a new instance of IMAttribute of
 * IM_TYPE_ATTR_FOREGROUND which specified by argument red, green and blue.
 * The value of each argument represents 0 for lowest intencity and 65535 for the
 * full intencity.
 *
 * @param red   intencity of red color.
 * @param green intencity of green color.
 * @param blue  intencity of blue color.
 *
 * @return This function returns a newly created instance of
 *         IM_TYPE_ATTR_FOREGROUND type IMAttribute.
 */ 
IMAttribute*            im_attr_foreground_new          (IMUInt16                red,
                                                         IMUInt16                green,
                                                         IMUInt16                blue);
/**
 * @brief Get the foreground color (in RGB) from the given attribute object.
 *
 * This function gets the values of each color component. If the argument red,
 * green, or blue is NULL, the value of that component shall not copied. If the
 * argument attr is not a IM_TYPE_FOREGROUND, the arguments red, green, blue
 * shall not changed.
 *
 * @param red   a pointer where the red component value shall be copied.
 * @param green a pointer where the green component value shall be copied.
 * @param blue  a pointer where the blue component value shall be copied.
 *
 * @return This function returns no value.
 */
void                    im_attr_foreground_get          (const IMAttribute      *attr,
                                                         IMUInt16               *red,
                                                         IMUInt16               *green,
                                                         IMUInt16               *blue);
/**
 * @brief Set the foreground color (in RGB) in the given attribute object.
 *
 * This function sets the each color component value of the argument attr with
 * the arguments red, green, blue. The value of each argument red, green and
 * blue represents 0 for lowest intencity and 65535 for the full intencity.
 *
 * @param red   intencity of red color component.
 * @param green intencity of green color component.
 * @param blue  intencity of blue color component.
 *
 * @return This function returns no value.
 */
void                    im_attr_foreground_set          (IMAttribute            *attr,
                                                         IMUInt16                red,
                                                         IMUInt16                green,
                                                         IMUInt16                blue);

/**
 * @brief Create a background attribute object with RGB color.
 *
 * The im_attr_background_new function creates a new instance of IMAttribute of
 * IM_TYPE_ATTR_BACKGROUND which specified by the arguments red, green, blue.
 * The value of each argument represents the intencity of color component.
 * 65535 is the full intencity.
 *
 * @param red   intencity of red color.
 * @param green intencity of green color.
 * @param blue  intencity of blue color.
 *
 * @return The im_attr_background_new function returns newly created instance
 *         of IM_TYPE_ATTR_BACKGROUND IMAttribute.
 */
IMAttribute*            im_attr_background_new          (IMUInt16                red,
                                                         IMUInt16                green,
                                                         IMUInt16                blue);
/**
 * @brief Get the background color (in RGB) from the given attribute object.
 *
 * This function gets the values of each color component of the argument attr.
 * If the argument red, green, or blue is NULL, the value of that component
 * shall not copied. If the argument attr is not a IM_TYPE_FOREGROUND, the
 * values pointed by the arguments red, green, blue shall not changed.
 *
 * @param red   a pointer where the red component value shall be copied.
 * @param green a pointer where the green component value shall be copied.
 * @param blue  a pointer where the blue component value shall be copied.
 *
 * @return This function returns no value.
 * */
void                    im_attr_background_get          (const IMAttribute      *attr,
                                                         IMUInt16               *red,
                                                         IMUInt16               *green,
                                                         IMUInt16               *blue);
/**
 * @brief Set the background color (in RGB) in the given attribute object.
 *
 * This function sets the each color component value of the argument attr with
 * the arguments red, green, blue. The value of each argument red, green and
 * blue represents intencity of color component, 0 for lowest intencity and
 * 65535 for the full intencity.
 *
 * @param red   intencity of red color component.
 * @param green intencity of green color component.
 * @param blue  intencity of blue color component.
 *
 * @return This function returns no value.
 */
void                    im_attr_background_set          (IMAttribute            *attr,
                                                         IMUInt16                red,
                                                         IMUInt16                green,
                                                         IMUInt16                blue);

/**
 * @brief Create a new underline attribute object.
 *
 * The im_attr_underline_new function creates new instance of IMAttribute
 * of IM_TYPE_ATTR_UNDERLINE type.
 *
 * @param type a value of IMAttrUnderline
 *
 * @return The im_attr_underline_new function returns newly created instance of
 *         IM_TYPE_ATTR_UNDERLINE IMAttribute.
 */
IMAttribute*            im_attr_underline_new           (IMAttrUnderline         type);
/**
 * @brief Get the underline type from the given attribute object.
 *
 * The im_attr_underline_get function get the underline style of the argument
 * attr.
 *
 * @param attr a pointer to an instance of IMAttribute.
 *
 * @return The im_attr_underline_get function 
 */
IMAttrUnderline         im_attr_underline_get           (const IMAttribute      *attr);
/**
 * @brief Set the underline type in the given attribute object.
 */
void                    im_attr_underline_set           (IMAttribute            *attr,
                                                         IMAttrUnderline         type);

/** @brief Create a new underline color attribute object. */
IMAttribute*            im_attr_underline_color_new     (IMUInt16                red,
                                                         IMUInt16                green,
                                                         IMUInt16                blue);
/** @brief Get the underline color (in RGB) from the given attribute object. */
void                    im_attr_underline_color_get     (const IMAttribute      *attr,
                                                         IMUInt16               *red,
                                                         IMUInt16               *green,
                                                         IMUInt16               *blue);
/** @brief Set the underline color (in RGB) in the given attribute object. */
void                    im_attr_underline_color_set     (IMAttribute            *attr,
                                                         IMUInt16                red,
                                                         IMUInt16                green,
                                                         IMUInt16                blue);

/** @brief Create a new strikethrough attribute object. */
IMAttribute*            im_attr_strikethrough_new       ();

/** @brief Create a new strikethrough color attribute object. */
IMAttribute*            im_attr_strikethrough_color_new (IMUInt16                red,
                                                         IMUInt16                green,
                                                         IMUInt16                blue);
/** @brief Get the strikethrough color (in RGB) from the given attribute object. */
void                    im_attr_strikethrough_color_get (const IMAttribute      *attr,
                                                         IMUInt16               *red,
                                                         IMUInt16               *green,
                                                         IMUInt16               *blue);
/** @brief Set the strikethrough color (in RGB) in the given attribute object. */
void                    im_attr_strikethrough_color_set (IMAttribute            *attr,
                                                         IMUInt16                red,
                                                         IMUInt16                green,
                                                         IMUInt16                blue);

/** @brief Create a new hightlight attribute object. */
IMAttribute*            im_attr_highlight_new           ();

/** @brief Create a new reverse attribute object. */
IMAttribute*            im_attr_reverse_new             ();

/** @brief Create a new string attribute object. */
IMAttribute*            im_attr_string_new              (const IMChar           *str);
/**
 * @brief Get the string from the given attribute object.
 *
 * The returned string should not be released by caller.
 */
const IMChar*           im_attr_string_get              (const IMAttribute      *attr);
/**
 * @brief Set the string in the given attribute object.
 *
 * In the attribute object, the original string would be released,
 * and replaced by a new copy of the given string.
 */
void                    im_attr_string_set              (IMAttribute            *attr,
                                                         const IMChar           *str);
/** @brief Set the string in the given attribute object with a static string. */
void                    im_attr_string_set_static       (IMAttribute            *attr,
                                                         const IMChar           *str);

/**
 * @brief Create a new attribute which holds an object.
 *
 * Ownership of given object will be assumed by the
 * newly created attribute object.
 */
IMAttribute*            im_attr_object_new              (IMPointer               object);
/**
 * @brief Get the object hold by an attribute.
 *
 * The returned object is owned by the attribute,
 * it shouldn't be modified or released by caller.
 */
IMPointer               im_attr_object_get              (const IMAttribute      *attr);
/**
 * @brief Return a clone of the object hold by this attribute.
 *
 * The returned object must be released with im_object_unref.
 */
IMPointer               im_attr_object_dup              (const IMAttribute      *attr);
void                    im_attr_object_set              (IMAttribute            *attr,
                                                         IMPointer               object);

/**
 * @brief Create an empty attribute list object.
 */
IMAttrList*             im_attr_list_new                (void);
/**
 * @brief Remove all attributes hold by the list.
 */
void                    im_attr_list_clear              (IMAttrList             *list);
/**
 * @brief Check if a IMAttrList object is empty.
 */
IMBool                  im_attr_list_empty              (const IMAttrList       *list);
/**
 * @brief Get the range covered by all attributes in a list.
 */
void                    im_attr_list_get_range          (const IMAttrList       *list,
                                                         IMUInt                 *start,
                                                         IMUInt                 *end);
/**
 * @brief Insert the given attribute into the IMAttrList.
 *
 * It will be inserted after all other attributes with
 * a matching @start
 *
 * @param list a IMAttrList
 * @param attr the attribute to insert.
 *        Ownership of this attribute is assumed by the list.
 */
void                    im_attr_list_insert             (IMAttrList             *list,
                                                         IMAttribute            *attr);
/**
 * @brief Insert the given attribute into the IMAttrList.
 *
 * It will be inserted before all other attributes with
 * a matching @start
 *
 * @param list a IMAttrList
 * @param attr the attribute to insert.
 *        Ownership of this attribute is assumed by the list.
 */
void                    im_attr_list_insert_before      (IMAttrList             *list,
                                                         IMAttribute            *attr);
/**
 * @brief Insert the given attribute into the IMAttrList
 *        while maintaining consistency of the list.
 *
 * It will replace any attributes of the same type on that segment
 * and be merged with any adjoining attributes that are identical.
 *
 * This function is slower than im_attr_list_insert() for creating
 * a attribute list in order (potentially much slower for large lists).
 * However, im_attr_list_insert() is not suitable for continually
 * changing a set of attributes since it never removes or combines
 * existing attributes.
 */
void                    im_attr_list_change             (IMAttrList             *list,
                                                         IMAttribute            *attr);
/**
 * @brief Splices attribute list other into list.
 *
 * This operation is equivalent to stretching every attribute
 * that applies at position pos in list by an amount len,
 * by calling im_attr_list_stretch(), and then calling
 * im_attr_list_change() with a copy of each attribute in other
 * in sequence (offset in position by pos).
 *
 * @param list a IMAttrList
 * @param other another IMAttrList
 * @param pos the position in list at which to insert other
 * @param len the length of the spliced segment.
 *        (Note that this must be specified since the
 *         attributes in other  may only be present at some
 *         subsection of this range)
 */
void                    im_attr_list_splice             (IMAttrList             *list,
                                                         IMAttrList             *other,
                                                         IMUInt                  pos,
                                                         IMUInt                  len);
/**
 * @brief Stretch a list at given position with given amount of length.
 *
 * All attributes at right side of the pos will be moved right accordingly.
 * All attributes which include the pos will be stretched accordingly.
 */
void                    im_attr_list_stretch            (IMAttrList             *list,
                                                         IMUInt                  pos,
                                                         IMUInt                  len);
/**
 * @brief Shrink a list at given position with given amount of length.
 *
 * All attributes will be moved/removed/clipped accordingly.
 * Total range of the list will be truncated by len.
 *
 * @param list an IMAttrList.
 * @param pos the position of the range to be shrunk.
 * @param len the length of the range to be shrunk.
 */
void                    im_attr_list_shrink             (IMAttrList             *list,
                                                         IMUInt                  pos,
                                                         IMUInt                  len);
/**
 * @brief Clear a given range of a list.
 *
 * All attributes in this range will be removed/clipped accordingly.
 * Total range of the list won't be affected, unless the
 * clear range is at the end of list range.
 *
 * @param list an IMAttrList.
 * @param pos the position of the range to be cleared.
 * @param len the length of the range to be cleared.
 */
void                    im_attr_list_clear_range        (IMAttrList             *list,
                                                         IMUInt                  pos,
                                                         IMUInt                  len);
/**
 * @brief Delete all attributes that match given type in given range.
 *
 * Attributes that match given attrtype in this range will be
 * removed/clipped accordingly.
 *
 * @param list an IMAttrList.
 * @param pos the position of the range to be deleted.
 * @param len the length of the range to be deleted.
 * @param attrtype The type of attribute to be deleted.
 */
void                    im_attr_list_remove             (IMAttrList             *list,
                                                         IMUInt                  pos,
                                                         IMUInt                  len,
                                                         IMType                  attrtype);
/**
 * @brief Get a sub portion of an IMAttrList.
 *
 * @param list an IMAttrList.
 * @param pos the position of sub list to be get.
 * @param len the length of sub lits to be get.
 * @return the newly created IMAttrList object which holds
 *         the specific sub portion of original list.
 *         It should be released by caller.
 */
IMAttrList*             im_attr_list_get_sub_list       (const IMAttrList       *list,
                                                         IMUInt                  pos,
                                                         IMUInt                  len);
/**
 * @brief Calls the given function against all attributes in a list one by one.
 * 
 * @param list an IMAttrList.
 * @param func the function to excutes for each item in the list
 */
void                    im_attr_list_foreach            (const IMAttrList       *list,
                                                         IMFunc                  func,
                                                         IMPointer               user_data);
/**
 * @brief Optimize a list.
 *
 * @param list an IMAttrList.
 * It actully just uses im_attr_list_change() to re-insert all attributes in the list.
 */
void                    im_attr_list_optimize           (IMAttrList             *list);

/**
 * @brief Create an iterator for a given list points to the first element.
 * @param list an IMAttrList to create the iterator from 
 * @return the newly created IMAttrIterator 
 */
IMAttrIterator*         im_attr_list_get_iterator       (IMAttrList             *list);

/**
 * @brief Clone an IMAttrIterator.
 * @param iterator is the source
 * @return the newly created IMAttrIterator 
 */
IMAttrIterator*         im_attr_iterator_clone          (const IMAttrIterator   *iterator);

/**
 * @brief Destroy an IMAttrIterator.
 * @param iterator an IMAttrIterator to be destoyed
 */
void                    im_attr_iterator_destroy        (IMAttrIterator         *iterator);

/**
 * @brief Advance an list iterator to the next attribute in the list.
 * @param iterator an IMAttrIterator of the next item in the list
 * @return IMBool success or not
 */
IMBool                  im_attr_iterator_next           (IMAttrIterator         *iterator);

/**
 * @brief Get the attribute pointed by an list iterator.
 * @param iterator an IMAttrIterator of the source item
 * @return the newly created IMAttribute
 */
IMAttribute*            im_attr_iterator_get            (const IMAttrIterator   *iterator);

/**
 * @brief Check whether an list iterator is valid or not.
 * @param iterator an IMAttrIterator of the next item in the list
 * @return the newly created IMAttrIterator 
 */
IMBool                  im_attr_iterator_valid          (const IMAttrIterator   *iterator);

/**
 * @brief Check whether two iterators point to the same attribute.
 * @param iterator1 an IMAttrIterator to be compared
 * @param iterator2 an IMAttrIterator to be compared
 * @return IMBool same or not
 */
IMBool                  im_attr_iterator_equal          (const IMAttrIterator   *iterator1,
                                                         const IMAttrIterator   *iterator2);
/**
 * @brief Remove an attribute pointed by a given iterator.
 * @param iterator an iterator points to an attribute.
 */

void                    im_attr_iterator_remove         (IMAttrIterator         *iterator);

IM_END_DECLS

#endif
/** @} */

/*
vi:ts=4:nowrap:ai:expandtab
*/
